package com.huabo.audit.service.impl;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hbfk.entity.DealUserToken;
import com.hbfk.entity.TblStaffUtil;
import com.hbfk.enums.ProcessVariableEnum;
import com.hbfk.util.DateUtil;
import com.hbfk.util.FtpUtil;
import com.hbfk.util.JsonBean;
import com.hbfk.util.PageInfo;
import com.hbfk.util.ResponseFormat;
import com.huabo.audit.enums.ProcessEnum;
import com.huabo.audit.oracle.entity.TblAttachment;
import com.huabo.audit.oracle.entity.TblAuditOption;
import com.huabo.audit.oracle.entity.TblCirculation;
import com.huabo.audit.oracle.entity.TblNbsjAuditplan;
import com.huabo.audit.oracle.entity.TblNbsjPlanProject;
import com.huabo.audit.oracle.entity.TblNbsjProject;
import com.huabo.audit.oracle.mapper.TblAttachmentMapper;
import com.huabo.audit.oracle.mapper.TblCirculationMapper;
import com.huabo.audit.oracle.mapper.TblNbsjAuditplanMapper;
import com.huabo.audit.oracle.mapper.TblNbsjPlanProjectMapper;
import com.huabo.audit.oracle.mapper.TblNbsjProjectMapper;
import com.huabo.audit.oracle.vo.TblNbsjAuditPlanVo;
import com.huabo.audit.service.ActivityPluginsService;
import com.huabo.audit.service.ProcessService;
import com.huabo.audit.service.TblAuditOptionService;
import com.huabo.audit.service.TblNbsjAuditplanService;
import com.huabo.audit.util.R;

/**
 * 描述:计划编号实现类
 * author: lyz
 * date: 2022-04-13
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class TblNbsjAuditplanServiceImpl implements TblNbsjAuditplanService {
    @Autowired
    private ActivityPluginsService activityPluginsService;
    @Autowired
    private TblNbsjProjectMapper tblNbsjProjectMapper;
    @Resource
    private TblNbsjAuditplanMapper tblNbsjAuditplanMapper;
    @Resource
	private TblAttachmentMapper tblAttachmentMapper;
    @Resource
	public TblNbsjPlanProjectMapper tblNbsjPlanProjectMapper;
    
    @Resource
   	public TblCirculationMapper tblCirculationMapper;
    
    @Resource
	private RuntimeService runtimeService;
	@Resource
	private HistoryService historyService;
	@Resource
	private RepositoryService repositoryService;
	@Resource 
	private TaskService taskService;
    @Resource
    private ProcessService processService;
    
    @Resource
    private TblAuditOptionService tblAuditOptionService;
    @Override
    public InputStream lookCurrentProcessImage(String taskId) {
		// 获取当前任务
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		if(task == null){
			return null;
		}
		//获取当前模型
		BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
        ProcessDiagramGenerator ge = new DefaultProcessDiagramGenerator();
        InputStream resource = ge.generateDiagram(bpmnModel, "png",
                runtimeService.getActiveActivityIds(task.getExecutionId()),
                new ArrayList<String>(), "宋体", "宋体", null, 1.0d);
        return resource;
    }
    @Override
	public JsonBean getNbsjAuditPlanListForMergeNbsjProject(String token) throws Exception {
    	TblStaffUtil loginStaff = DealUserToken.parseUserToken(token);
		if(loginStaff == null) {
			return ResponseFormat.retParam(0,20006,null);
		}
		Map<String,Object> resultMap = new HashMap<String,Object>(0);
    	List<TblNbsjAuditplan> planList = this.tblNbsjAuditplanMapper.selectPlanListForMergeNbsjProject(loginStaff.getCurrentOrg().getOrgid());
    	resultMap.put("planList", planList);
		return ResponseFormat.retParam(1,200,planList);
	}
    @Override
	public JsonBean planManagePageList(String token, Integer pageNumber, Integer pageSize,TblNbsjAuditPlanVo tblNbsjAuditPlanVo, String planStartDate, String planEndDate) throws Exception {
    	
    	TblStaffUtil loginStaff = DealUserToken.parseUserToken(token);
		if(loginStaff == null) {
			return ResponseFormat.retParam(0,20006,null);
		}
		
    	if(pageNumber == null) {
    		pageNumber = 1;
    	}
    	if(pageSize==null) {
    		pageSize=15;
    	}
    	Map<String,Object> resultMap = new HashMap<String,Object>(0);
    	
    	PageInfo<TblNbsjAuditplan> pageInfo = new PageInfo<TblNbsjAuditplan>();
    	
    	pageInfo.setPageSize(pageSize);
    	pageInfo.setCurrentPage(pageNumber);
    	
    	pageInfo.setTlist(this.tblNbsjAuditplanMapper.selectNbsjAuditPlanListByPageInfo(pageInfo,planStartDate,planEndDate,loginStaff.getCurrentOrg().getOrgid(),tblNbsjAuditPlanVo));
    	pageInfo.setTotalRecord(this.tblNbsjAuditplanMapper.selectNbsjAuditPlanCountByPageInfo(pageInfo,planStartDate,planEndDate,loginStaff.getCurrentOrg().getOrgid(),tblNbsjAuditPlanVo));
    	pageInfo.getTotalPage();
    	String identifier = activityPluginsService.getoNState(ProcessEnum.SJ_JHGL.name());
    	resultMap.put("identifier", identifier);
    	resultMap.put("pageInfo", pageInfo);
    	return ResponseFormat.retParam(1,200,resultMap);
	}
    

    
    @Override
	public JsonBean mergePlanManageInfo(TblNbsjAuditplan plan, String token, String planStartTime, String planEndTime,String attIds) throws Exception {
    	TblStaffUtil loginStaff = DealUserToken.parseUserToken(token);
		if(loginStaff == null) {
			return ResponseFormat.retParam(0,20006,null);
		}
		
		Integer count = this.tblNbsjAuditplanMapper.selectPlanCodeByOrgid(plan);
		if(count > 0) {
			return ResponseFormat.retParam(0,202,null);
		}
    	
		
		if(planStartTime != null && !"".equals(planStartTime)) {
			plan.setStarttime(DateUtil.formatDate(planStartTime,"yyyy-MM-dd"));
		}
		if(planEndTime != null && !"".equals(planEndTime)) {
			plan.setEndtime(DateUtil.formatDate(planEndTime,"yyyy-MM-dd"));
		}
		
		
		if(plan.getPlanid() != null) {
			//修改；
			this.tblNbsjAuditplanMapper.updateEntity(plan);
		}else {
			//新增；
			plan.setCreatestaffid(loginStaff.getStaffid());
			plan.setAuditorgid(loginStaff.getCurrentOrg().getOrgid());
			plan.setCreatetime(new Date());
			plan.setStatus(0);
			this.tblNbsjAuditplanMapper.insertEntity(plan);
		}
		Map<String,Object> resultMap = new HashMap<String,Object>(0);
		
		if(attIds != null && !"".equals(attIds)) {
			String[] attId = attIds.split(",");
			for (String aid : attId) {
				this.tblNbsjAuditplanMapper.insertAttInfoForPlan(plan.getPlanid(),aid);
			}
		}
		resultMap.put("auditPlan",plan);
		return ResponseFormat.retParam(1,200,resultMap);
	}

    @Override
	public JsonBean findNbsjAuditPlanDetail(String token, Integer planid) throws Exception {
    	TblStaffUtil loginStaff = DealUserToken.parseUserToken(token);
		if(loginStaff == null) {
			return ResponseFormat.retParam(0,20006,null);
		}
		Map<String,Object> resultMap = new HashMap<String,Object>(0);
		TblNbsjAuditplan plan = this.tblNbsjAuditplanMapper.selectNbsjAuditPlanEntityById(planid);
		List<TblNbsjPlanProject> planList =  this.tblNbsjPlanProjectMapper.selectPlanProjectListInfoByPlanId(planid);
		plan.setPlanProjectList(planList);
		resultMap.put("auditPlan", plan);
		return ResponseFormat.retParam(1,200,resultMap);
	}

    
    /**
     * @description 删除计划
     * @author lyz
     * @date 2022/4/19 11:03
     */
    @Override
    public JsonBean deletePlanManageByPlanId(Integer planId, String token) throws Exception {
    	TblStaffUtil loginStaff = DealUserToken.parseUserToken(token);
		if(loginStaff == null) {
			return ResponseFormat.retParam(0,20006,null);
		}
		TblNbsjAuditplan plan = this.tblNbsjAuditplanMapper.selectNbsjAuditPlanEntityById(planId);
		
		if(plan == null) {
			return ResponseFormat.retParam(1,50001,null);
		}
		
		if (plan.getOpinionstatus() == TblNbsjAuditplan.SPNO) {//
			//删除审计计划中的审计项目
			this.tblNbsjPlanProjectMapper.deletePlanProjectByPlanId(planId);
			//删除所有附件
			List<String> attIdList = this.tblNbsjAuditplanMapper.findAttIdListByPlanId(planId);
			for (String attId : attIdList) {
				this.deleteRealtionAttInfo(attId);
			}
			this.tblNbsjAuditplanMapper.deleteAuditPlanEntityById(planId);
			return ResponseFormat.retParam(1,200,null);
        } else {
            return ResponseFormat.retParam(1,50001,null);
        }
    }

	@Override
	public R removeAttInfoByAttId(String token, String attId) throws Exception {
		TblStaffUtil loginStaff = DealUserToken.parseUserToken(token);
		if(loginStaff == null) {
			return R.fail("用户已失效！");
		}
        return this.deleteRealtionAttInfo(attId);
	}

	private R deleteRealtionAttInfo(String attId) throws Exception {
		boolean b = false;
        TblAttachment att = this.tblAttachmentMapper.selectEntityById(attId);
//        if (att == null) {
//            return R.fail("附件不存在或已经删除");
//        }
//        int index = att.getAttpath().lastIndexOf("/") + 1; //右边第一个/
//        String path = att.getAttpath().substring(0, index);
//        String fileName = att.getAttpath().substring(index);
//        try {
//            b = FtpUtil.removeFile(fileName, path);
//        } catch (Exception e) {
//        	return R.fail("文件删除失败！");
//        }
//        if (!b) {
//        	return R.fail("文件删除失败！");
//        }
        this.tblNbsjAuditplanMapper.deleteFileInfoByAttId(att.getAttid());
        this.tblAttachmentMapper.deleteEntity(att.getAttid());
        
        return R.success();
	}

	@Override
	public JsonBean getNbsjAuditPlanDateInfo(String token, Integer planId) throws Exception {
		TblStaffUtil user = DealUserToken.parseUserToken(token);
		if(user == null) {
			return ResponseFormat.retParam(0,20006,null);
		}
		Map<String,Object> resultMap = new HashMap<String,Object>(0);
		TblNbsjAuditplan plan = this.tblNbsjAuditplanMapper.selectNbsjAuditPlanEntityById(planId);
		resultMap.put("planStartDate", DateUtil.parseDate(plan.getStarttime(),"yyyy-MM-dd"));
		resultMap.put("planEndDate", DateUtil.parseDate(plan.getEndtime(), "yyyy-MM-dd"));
		
		return ResponseFormat.retParam(1,200,resultMap);
	}
	
	
	@Override
	public JsonBean getAuditPlanAttInfo(String token, Integer planId) throws Exception {
		TblStaffUtil user = DealUserToken.parseUserToken(token);
		if(user == null) {
			return ResponseFormat.retParam(0,20006,null);
		}
		Map<String,Object> resultMap = new HashMap<String,Object>(0);
		
		List<TblAttachment> attList = this.tblAttachmentMapper.selectAttListByAuditPlanId(planId);
		resultMap.put("attList", attList);
		return ResponseFormat.retParam(1,200,attList);
	}
	
	@Override
	public JsonBean submitAuditplanArrpoval(String token, Integer planId) throws Exception {
		
		TblStaffUtil user = DealUserToken.parseUserToken(token);
		if(user == null) {
			return ResponseFormat.retParam(0,20006,null);
		}
    	
    	TblNbsjAuditplan plan = this.tblNbsjAuditplanMapper.selectNbsjAuditPlanEntityById(planId);
        TblCirculation cir = new TblCirculation();
        try {
           
           cir.setCytype(TblCirculation.TYPE_JHSP);
           cir.setCycode(plan.getPalnyear());
           cir.setCyname(plan.getPlanname());
           cir.setCydate(new Date());
           cir.setCystate(TblCirculation.STATE_FQ);
           cir.setCyurl(TblCirculation.URL_JHSP+plan.getPlanid());
           cir.setCyStaffid(user.getStaffid().toString());
           this.tblCirculationMapper.saveTblCirculation(cir);
           
           Map<String, Object> variables= new HashMap<String, Object>();
           variables.put(ProcessVariableEnum.model.toString(), cir);
           ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(ProcessEnum.SJ_JHGL.name(),cir.getCyid().toString(), variables);
           Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
           cir.setTaskid(task.getId());
           //流程定义Id
           String businessKey = processInstance.getBusinessKey();
           String definitionId = processInstance.getProcessDefinitionId();
           cir.setBusinesskey(businessKey);
           cir.setDefinitionid(definitionId);
           this.tblCirculationMapper.updateCirculationInfoById(cir);
           taskService.complete(task.getId());
           plan.setOpinionstatus(TblNbsjAuditplan.SPKA);
           this.tblNbsjAuditplanMapper.updateEntity(plan);
        } catch (Exception e) {
        	e.printStackTrace();
        	if(cir != null && cir.getCyid() != null) {
        		this.tblCirculationMapper.deleteEntityById(cir.getCyid());
        	}
        	return ResponseFormat.retParam(1,30002,null);
        }	
        return ResponseFormat.retParam(1,200,null);
	}

	@Override
	public JsonBean getAuditPlanApprovalInfo(String token, Integer planId, String taskId,Integer cyId) throws Exception {
		TblStaffUtil staff = DealUserToken.parseUserToken(token);
		if(staff == null) {
			return ResponseFormat.retParam(0,20006,null);
		}
		Map<String,Object> resultMap = new HashMap<String,Object>(0);
		
		
        TblNbsjAuditplan plan = this.tblNbsjAuditplanMapper.selectNbsjAuditPlanEntityById(planId);
        List<String> btnList = null;
    	if(plan!=null){
    		if(StringUtils.isNotBlank(taskId) && plan.getOpinionstatus() != TblNbsjAuditplan.SPTZ){
    			btnList = processService.getButtonsForTransition(taskId);
    			resultMap.put("btnList", btnList);
    		}
    	
    		List<TblAuditOption> ao = tblAuditOptionService.findOptionByRelationId(plan.getPlanid().toString(),cyId);
    		if (cyId != null){
    			TblCirculation cy = this.tblCirculationMapper.findById(cyId.toString());
    			resultMap.put("cy", cy);
    		}
    		List<TblNbsjPlanProject> planProjectList =  this.tblNbsjPlanProjectMapper.selectPlanProjectListInfoByPlanId(planId);
    		
    		resultMap.put("taskId", taskId);
    		resultMap.put("aoptionList", ao);
    		resultMap.put("cyId", cyId);
    		resultMap.put("planId", planId);
    		
    		resultMap.put("plan", plan);
    		resultMap.put("planProjectList", planProjectList);
    		resultMap.put("projectCount", planProjectList.size());
    	}
    	return ResponseFormat.retParam(1,200,resultMap);
	}

	@Override
	public JsonBean dealAuditPlanApporvalInfo(String token, Integer cyId, String taskId, String transition,
			String optDesc, String planId) throws Exception {
		TblStaffUtil staff = DealUserToken.parseUserToken(token);
		if(staff == null) {
			return ResponseFormat.retParam(0,20006,null);
		}
		JsonBean jsonBean = null;
		Map<String,Object> resultMap = new HashMap<String,Object>(0);
		
		TblCirculation cy = this.tblCirculationMapper.findById(cyId.toString());
		if (null != cy) {
			Map<String, Object> variables = new HashMap<>();
			variables.put(ProcessVariableEnum.model.toString(), cy);
			if (StringUtils.isNotBlank(transition)) {
				variables.put(ProcessVariableEnum.transition.toString(), transition);
			}
			try {
				taskService.claim(taskId, staff.getStaffid().toString());
				taskService.complete(taskId, variables);
			} catch (Exception e) {
				e.printStackTrace();
				return ResponseFormat.retParam(0,30002,null);
			}
			//添加审批意见
			TblAuditOption opt = new TblAuditOption();
			opt.setCyid(cy.getCyid());
			opt.setOptStaffid(staff.getStaffid());
			opt.setStaffidName(staff.getRealname());
			opt.setOptDesc(optDesc);
			opt.setRelationId(new BigDecimal(planId));
			opt.setOptState(transition);
			jsonBean = this.tblAuditOptionService.saveAuditOptionInfo(cy,opt);
		}
		return jsonBean;
	}

	@Override
	public JsonBean getAuditPlanViewInfo(String token, String planName, String planYear, Integer pageNumber,
			Integer pageSize) throws Exception {
		TblStaffUtil loginStaff = DealUserToken.parseUserToken(token);
		if(loginStaff == null) {
			return ResponseFormat.retParam(0,20006,null);
		}
		
    	if(pageNumber == null) {
    		pageNumber = 1;
    	}
    	if(pageSize==null) {
    		pageSize=15;
    	}
    	Map<String,Object> resultMap = new HashMap<String,Object>(0);
    	
    	TblNbsjAuditplan tblNbsjAuditplan = new TblNbsjAuditplan();
    	PageInfo<TblNbsjAuditplan> pageInfo = new PageInfo<TblNbsjAuditplan>();
    	tblNbsjAuditplan.setAuditorgid(loginStaff.getCurrentOrg().getOrgid());
    	tblNbsjAuditplan.setPlanname(planName);
    	tblNbsjAuditplan.setPalnyear(planYear);
    	pageInfo.setCondition(tblNbsjAuditplan);
    	pageInfo.setPageSize(pageSize);
    	pageInfo.setCurrentPage(pageNumber);
    	
    	pageInfo.setTlist(this.tblNbsjAuditplanMapper.selectAuditPlanListView(pageInfo));
    	pageInfo.setTotalRecord(this.tblNbsjAuditplanMapper.selectAuditPlanCountView(pageInfo));
    	resultMap.put("pageInfo", pageInfo);
    	return  ResponseFormat.retParam(1,200,resultMap);
	}

	@Override
	public JsonBean findNbsjAuditPlanViewDetail(String token, Integer planid) throws Exception {
		TblStaffUtil loginStaff = DealUserToken.parseUserToken(token);
		if(loginStaff == null) {
			return ResponseFormat.retParam(0,20006,null);
		}
		Map<String,Object> resultMap = new HashMap<String,Object>(0);
		TblNbsjAuditplan plan = this.tblNbsjAuditplanMapper.selectNbsjAuditPlanEntityById(planid);
		List<TblNbsjProject> projectList =  this.tblNbsjProjectMapper.selectProjectListInfoByPlanId(planid);
		//plan.setProjectList(projectList);
		resultMap.put("auditPlan", plan);
		return ResponseFormat.retParam(1,200,resultMap);
	}
}
	
